



#include <cstdio>

static unsigned long *GetCRC32Table( unsigned long *crc_table ) {
   
    if ( !crc_table )
    {
       
        crc_table = new unsigned long[256];

       
        if ( crc_table )
        {
           
            unsigned long crc ;
            int i, j ;

            for(i = 0; i < 256; i++)
            {
                crc = i;
                for (j = 8; j > 0; j--)
                {
                    if (crc & 1) crc = (crc >> 1) ^ 0xEDB88320UL;
                    else         crc >>= 1;
                }
                crc_table[i] = crc;
            }
        }
    }

   
    return ( crc_table ) ;
}

unsigned long GetFileCRC32(const char* file) {
    static unsigned long *crc_table = NULL;
    unsigned long crc = 0;

    if (file)
    {
       
        crc_table = GetCRC32Table( crc_table ) ;

       
        if ( crc_table )
        {
           
            FILE *fp = fopen(file, "r");

           
            if (fp)
            {
               
                int ch;

                crc = 0xFFFFFFFFUL;
                while ((ch = getc(fp)) != EOF)
                    { crc = (crc>>8) ^ crc_table[ (crc^ch) & 0xFF ]; }

                crc ^= 0xFFFFFFFFUL ;

               
                fclose(fp);
            }
        }
    }

   
    if ( crc_table ) { delete[] crc_table; }

   
   
    crc_table = NULL;

   
    return( crc ) ;
}

unsigned long GetTextCRC32(const char* text) {
    static unsigned long *crc_table = NULL;
    unsigned long crc = 0;

    if (text)
    {
       
        crc_table = GetCRC32Table( crc_table ) ;

       
        if ( crc_table )
        {
           
            crc = 0xFFFFFFFFUL;
            while (*text)
                { crc = (crc>>8) ^ crc_table[ (crc^(*text++)) & 0xFF ]; }

            crc ^= 0xFFFFFFFFUL ;
        }
    }

   
    if ( crc_table ) { delete[] crc_table; }

   
   
    crc_table = NULL;

   
    return( crc ) ;
}
